package com.bi.utils;

import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

/**
 * Bean转换工具类
 * 
 * @author BI Platform Team
 * @since 1.0.0
 */
public class BeanCopyUtils {

    /**
     * 复制单个对象
     * 
     * @param source 源对象
     * @param targetClass 目标类
     * @param <T> 目标类型
     * @return 目标对象
     */
    public static <T> T copy(Object source, Class<T> targetClass) {
        if (source == null) {
            return null;
        }
        try {
            T target = targetClass.newInstance();
            BeanUtils.copyProperties(source, target);
            return target;
        } catch (Exception e) {
            throw new RuntimeException("Bean复制失败", e);
        }
    }

    /**
     * 复制单个对象（使用Supplier）
     * 
     * @param source 源对象
     * @param targetSupplier 目标对象供应商
     * @param <T> 目标类型
     * @return 目标对象
     */
    public static <T> T copy(Object source, Supplier<T> targetSupplier) {
        if (source == null) {
            return null;
        }
        T target = targetSupplier.get();
        BeanUtils.copyProperties(source, target);
        return target;
    }

    /**
     * 复制对象列表
     * 
     * @param sourceList 源对象列表
     * @param targetClass 目标类
     * @param <T> 目标类型
     * @return 目标对象列表
     */
    public static <T> List<T> copyList(List<?> sourceList, Class<T> targetClass) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return Collections.emptyList();
        }

        List<T> targetList = new ArrayList<>(sourceList.size());
        for (Object source : sourceList) {
            T target = copy(source, targetClass);
            targetList.add(target);
        }
        return targetList;
    }

    /**
     * 复制对象列表（使用Supplier）
     * 
     * @param sourceList 源对象列表
     * @param targetSupplier 目标对象供应商
     * @param <T> 目标类型
     * @return 目标对象列表
     */
    public static <T> List<T> copyList(List<?> sourceList, Supplier<T> targetSupplier) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return Collections.emptyList();
        }

        List<T> targetList = new ArrayList<>(sourceList.size());
        for (Object source : sourceList) {
            T target = copy(source, targetSupplier);
            targetList.add(target);
        }
        return targetList;
    }
}